package Controller

import (
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"log"
	"strings"
	"time"
	"web_back_go/Common"
	"web_back_go/DAO/gorm"
	"web_back_go/DAO/gorm/GormModel"
	"web_back_go/Dto"
	"web_back_go/Middleware"
	"web_back_go/Response"
	"web_back_go/Service"
	"web_back_go/Util"
)

/*
ConfirmOrder
@Description: 结算，生成订单信息
@param c
@return
*/
func ConfirmOrder(c *gin.Context) {
	orderParam := &Dto.OrderParam{}
	if err := c.ShouldBindJSON(orderParam); err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "参数错误",
			Sign:    nil,
			Version: "V1.0.0",
		})
		return
	}
	userId, err := Common.GetUserId(c)
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00004",
			Data:    nil,
			Success: true,
			Msg:     "Unauthorized",
		})
		return
	}

	db := gorm.Db.Begin()
	//延迟回滚或提交事务
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()
			c.JSON(200, Response.ResponseBody{
				Code:    "A00005",
				Data:    nil,
				Success: true,
				Msg:     "服务器出了点小差",
			})
		} else if err != nil {
			db.Rollback()
		} else {
			db.Commit()
		}
	}()
	/*
	 select addr_id,user_id,receiver,province,city,area,province_id,city_id,area_id,addr,mobile,common_addr
	    from tz_user_addr where user_id = #{userId} and addr_id = #{addrId}
	*/

	//UserAddr userAddr = userAddrService.getUserAddrByUserId(orderParam.getAddrId(), userId);
	userAddr := Service.GetUserAddrByUserId(orderParam.AddrId, userId)
	var userAddrDto Dto.UserAddrDto
	if err := copier.CopyWithOption(&userAddrDto, &userAddr, copier.Option{IgnoreEmpty: true, DeepCopy: true}); err != nil {
		panic(err)
	}

	//组装获取用户提交的购物车商品项
	var shopCartItems []Dto.ShopCartItemDto
	shopCartItems = GetShopCartItemsByOrderItems(orderParam.BasketIds, orderParam.OrderItem, userId)
	if Util.SliceIsEmpty(shopCartItems) {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "请选择您需要的商品加入购物车",
		})
	}
	// 根据店铺组装购车中的商品信息，返回每个店铺中的购物车商品信息
	var shopCarts []Dto.ShopCartDto = GetShopCarts(shopCartItems)
	// 将要返回给前端的完整的订单信息
	var shopCartOrderMergerDto Dto.ShopCartOrderMergerDto

	shopCartOrderMergerDto.UserAddr = userAddrDto

	// 所有店铺的订单信息
	shopCartOrders := make([]Dto.ShopCartOrderDto, 0)
	actualTotal := 0.0
	total := 0.0
	totalCount := 0
	orderReduce := 0.0
	for _, shopCart := range shopCarts {
		// 每个店铺的订单信息
		var shopCartOrder Dto.ShopCartOrderDto
		shopCartOrder.ShopId = shopCart.ShopId
		shopCartOrder.ShopName = shopCart.ShopName
		shopCartItemDiscounts := shopCart.ShopCartItemDiscounts
		// 店铺中的所有商品项信息
		shopAllShopCartItems := make([]Dto.ShopCartItemDto, 0)
		for _, shopCartItemDiscount := range shopCartItemDiscounts {
			discountShopCartItems := shopCartItemDiscount.ShopCartItems
			shopAllShopCartItems = append(shopAllShopCartItems, discountShopCartItems...)
		}
		shopCartOrder.ShopCartItemDiscounts = shopCartItemDiscounts

		//-------------------计算金额------------------

		tmpOrderParam := orderParam
		tmpUserid := userId
		// 订单的地址信息
		tmpUserAddr := Service.GetUserAddrByUserId(tmpOrderParam.AddrId, tmpUserid)
		tmpTotal := 0.0
		tmpTotalCount := 0
		tmptransfee := 0.0
		for _, shopCartItem := range shopAllShopCartItems {
			// 获取商品信息
			var product *GormModel.TzProd
			gorm.Db.Model(&GormModel.TzProd{}).Where("prod_id = ?", shopCartItem.ProdId).First(&product)
			// 获取sku信息
			var sku *GormModel.TzSku
			gorm.Db.Model(&GormModel.TzSku{}).Where("sku_id = ?", shopCartItem.SkuId).First(&sku)
			if product == nil || sku == nil {
				c.JSON(200, Response.ResponseBody{
					Code:    "A00001",
					Data:    nil,
					Success: true,
					Msg:     "购物车包含无法识别的商品",
				})
				return
			}
			if *product.Status != 1 || *sku.Status != 1 {
				c.JSON(200, Response.ResponseBody{
					Code:    "A00001",
					Data:    nil,
					Success: true,
					Msg:     "商品[" + *product.ProdName + "]已下架",
				})
				return
			}
			tmpTotalCount = shopCartItem.ProdCount + tmpTotalCount
			tmpTotal = shopCartItem.ProductTotalAmount + tmpTotal
			// 用户地址如果为空，则表示该用户从未设置过任何地址相关信息
			if tmpUserAddr != nil {
				// 每个产品的运费相加
				tmptransfee = tmptransfee + Common.CalculateTransfee(shopCartItem, *tmpUserAddr)
			}
			shopCartItem.ActualTotal = shopCartItem.ProductTotalAmount
			shopCartOrder.ActualTotal = tmpTotal + tmptransfee
			shopCartOrder.Total = tmpTotal
			shopCartOrder.TotalCount = tmpTotalCount
			shopCartOrder.Transfee = tmptransfee
		}
		//	actualTotal = Arith.add(actualTotal,shopCartOrder.getActualTotal());
		actualTotal = actualTotal + shopCartOrder.ActualTotal
		total = total + shopCartOrder.Total
		totalCount = totalCount + shopCartOrder.TotalCount
		orderReduce = orderReduce + shopCartOrder.ShopReduce
		shopCartOrders = append(shopCartOrders, shopCartOrder)
	}
	shopCartOrderMergerDto.ActualTotal = actualTotal
	shopCartOrderMergerDto.Total = total
	shopCartOrderMergerDto.TotalCount = totalCount
	shopCartOrderMergerDto.ShopCartOrders = shopCartOrders
	shopCartOrderMergerDto.OrderReduce = orderReduce
	//将订单缓存到redis中,通过userId作为key
	Middleware.SetCache("ConfirmOrderCache", userId, shopCartOrderMergerDto, time.Hour*1)

	c.JSON(200, Response.ResponseBody{
		Code:    "00000",
		Data:    shopCartOrderMergerDto,
		Success: true,
		Msg:     "Success",
	})
}
func GetShopCartItemsByOrderItems(basketId []int64, orderItem *Dto.OrderItemParam, userId string) []Dto.ShopCartItemDto {
	// 如果 orderItem 为空，则返回空列表
	if orderItem == nil && len(basketId) == 0 {
		return []Dto.ShopCartItemDto{}
	}
	// 当立即购买时，没有提交的订单是没有购物车信息的
	if Util.SliceIsEmpty(basketId) && orderItem != nil {
		db := gorm.Db
		var sku *GormModel.TzSku
		db.Where("sku_id = ?", orderItem.SkuId).First(&sku)
		if sku == nil {
			panic("订单包含无法识别的商品")
		}
		var prod *GormModel.TzProd
		db.Where("prod_id = ?", orderItem.ProdId).First(&prod)
		if prod == nil {
			panic("订单包含无法识别的商品")
		}
		// 拿到购物车的所有item
		var shopCartItemDto Dto.ShopCartItemDto
		shopCartItemDto.BasketId = -1
		shopCartItemDto.SkuId = orderItem.SkuId
		shopCartItemDto.ProdCount = orderItem.ProdCount
		shopCartItemDto.ProdId = orderItem.ProdId
		shopCartItemDto.SkuName = *sku.SkuName
		if strings.TrimSpace(*sku.Pic) == "" {
			shopCartItemDto.Pic = *prod.Pic
		} else {
			shopCartItemDto.Pic = *sku.Pic
		}
		shopCartItemDto.ProdName = *sku.ProdName
		shopCartItemDto.ProductTotalAmount = *sku.Price * float64(orderItem.ProdCount)
		shopCartItemDto.Price = *sku.Price
		shopCartItemDto.DistributionCardNo = orderItem.DistributionCardNo
		shopCartItemDto.BasketDate = Common.GetCurrentTime()
		var shopDetail *GormModel.TzShopDetail
		db.Where("shop_id = ?", orderItem.ShopId).First(&shopDetail)
		shopCartItemDto.ShopId = shopDetail.ShopID
		shopCartItemDto.ShopName = shopDetail.ShopName
		//		  return Collections.singletonList(shopCartItemDto);
		return []Dto.ShopCartItemDto{shopCartItemDto}
	}
	dbShopCartItems := getShopCartItems(userId)
	//basketIds := make(map[int64]bool)
	//var filteredItems []Dto.ShopCartItemDto
	//for _, item := range dbShopCartItems {
	//	if basketIds[item.BasketId] {
	//		filteredItems = append(filteredItems, item)
	//	}
	//}
	//return filteredItems

	// 避免零值问题
	basketIds := make(map[int64]struct{})
	for _, id := range basketId {
		basketIds[id] = struct{}{}
	}

	var filteredItems []Dto.ShopCartItemDto
	for _, item := range dbShopCartItems {
		if _, exists := basketIds[item.BasketId]; exists {
			filteredItems = append(filteredItems, item)
		}
	}
	return filteredItems

	//---------
	//basketIdSet := make(map[string]struct{})
	//for _, id := range basketId {
	//	basketIdSet[id] = struct{}{}
	//}
	//
	//// 过滤切片
	//var result []ShopCartItemDto
	//for _, item := range dbShopCartItems {
	//	if _, exists := basketIdSet[item.BasketId]; exists {
	//		result = append(result, item)
	//	}
	//}
}

func getShopCartItems(userId string) []Dto.ShopCartItemDto {
	var shopCartItemDtoList []Dto.ShopCartItemDto
	db := gorm.Db
	err := db.Raw("SELECT tb.*,tb.basket_count as prod_count,tsd.shop_name,IFNULL(ts.pic,tp.pic)AS pic,ts.price,ts.ori_price,tp.brief,ts.properties,ts.prod_name,ts.sku_name "+
		"FROM tz_basket tb "+
		"LEFT JOIN tz_shop_detail tsd ON tb.shop_id = tsd.shop_id "+
		"LEFT JOIN tz_prod tp ON tb.prod_id = tp.prod_id "+
		"LEFT JOIN tz_sku ts ON tb.sku_id = ts.sku_id "+
		"WHERE tp.status = 1 AND ts.status =1 AND tb.user_id =? "+
		"ORDER BY tb.`basket_id` DESC", userId).Scan(&shopCartItemDtoList).Error
	if err != nil {
		panic(err)
	}
	//for循环改变的是副本 浅拷贝！！！
	for i := range shopCartItemDtoList {
		shopCartItemDtoList[i].ProductTotalAmount = shopCartItemDtoList[i].Price * float64(shopCartItemDtoList[i].ProdCount)

	}
	return shopCartItemDtoList
}
func filterShopCartItems(items []Dto.ShopCartItemDto, basketIds map[int64]bool) []Dto.ShopCartItemDto {
	var filteredItems []Dto.ShopCartItemDto
	for _, item := range items {
		if basketIds[item.BasketId] {
			filteredItems = append(filteredItems, item)
		}
	}
	return filteredItems
}

/*
SubmitOrders
@Description: 根据传入的参数判断是否为购物车提交订单，同时对购物车进行删除，用户开始进行支付
*/
func SubmitOrders(c *gin.Context) {
	submitOrderParam := &Dto.SubmitOrderParam{}
	if err := c.ShouldBindJSON(&submitOrderParam); err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "参数错误",
		})
		return
	}
	userId, _ := Common.GetUserId(c)
	var mergerOrder *Dto.ShopCartOrderMergerDto
	Middleware.GetCache("ConfirmOrderCache", userId, &mergerOrder)
	log.Printf("mergerOrder: %v", mergerOrder)
	if mergerOrder == nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "订单已过期，请重新下单",
		})
		return
	}
	orderShopParams := submitOrderParam.OrderShopParam
	shopCartOrders := mergerOrder.ShopCartOrders
	// 设置备注
	if Util.SliceIsNotEmpty(orderShopParams) {
		for _, orderShopParam := range orderShopParams {
			for _, shopCartOrder := range shopCartOrders {
				if shopCartOrder.ShopId == orderShopParam.ShopID {
					shopCartOrder.Remarks = orderShopParam.Remarks
				}
			}
		}
	}
	var orders []GormModel.TzOrder = Service.SubmitOrders(userId, *mergerOrder)
	var orderNumbers strings.Builder
	for _, order := range orders {
		orderNumbers.WriteString(order.OrderNumber)
		orderNumbers.WriteString(",")
	}
	// 获取拼接好的字符串
	orderNumbersResult := orderNumbers.String()
	// 去掉末尾的逗号
	if len(orderNumbersResult) > 0 {
		orderNumbersResult = strings.TrimRight(orderNumbersResult, ",")
	}
	log.Printf("orderNumbersResult: %v", orderNumbersResult)
	/*
		isShopCartOrder := false
		// 移除缓存
		for _, shopCartOrder := range shopCartOrders {
			for _, shopCartItemDiscount := range shopCartOrder.ShopCartItemDiscounts {
				for _, shopCartItem := range shopCartItemDiscount.ShopCartItems {
					basketId := shopCartItem.BasketId
					if basketId != 0 {
						isShopCartOrder = true
					}
				}
			}
		}*/
	//将订单在redis中删除
	Middleware.DeleteCache("ConfirmOrderCache", userId)
	c.JSON(200, Response.ResponseBody{
		Code:    "00000",
		Data:    Dto.OrderNumbersDto{OrderNumbers: orderNumbersResult},
		Success: true,
		Msg:     "Success",
	})
}
